package com.xhs.aop;

import com.xhs.annotation.DataSource;
import com.xhs.service.UserService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

/**
 * 数据源切面
 * @author wudawei 356110537@qq.com
 * @date 2016-12-14
 *
 */
@Component
public class DataSourceAOP {
	
	private String dataSourceName;

	public void before(JoinPoint point){
		//初始化数据源
		dataSourceName = null;
		//获取当前执行的方法
		Signature signature = point.getSignature(); 
		MethodSignature methodSignature = (MethodSignature)signature;    
		Method method = methodSignature.getMethod();
		String className = method.getDeclaringClass().getName();
		String methodName = method.getName();
		
//		System.out.println("[ 实现类: "+ cls.getName() +"]");
//		System.out.println("[ 拦截 "+ className +" 中 "+ methodName +" ]");
		
		//通过反射获取类对象
		Class<?> cls = point.getTarget().getClass();
		if (hasDataSource(cls) != null) {
			dataSourceName = hasDataSource(cls);
		}
		
		if (method.isAnnotationPresent(DataSource.class)) {
			//获取方法上的注解
			DataSource methodAnnotation = method.getAnnotation(DataSource.class);
			if (methodAnnotation != null) {
				dataSourceName = methodAnnotation.value();
			}
		}
		
		//设置数据源
		if (dataSourceName != null && !dataSourceName.equals("")) {
			HandleDataSource.putDataSource(dataSourceName);
			System.out.println("[ 动态切换数据源:=====> "+className + "." + methodName + " use { "+ dataSourceName +" } 数据源... ]");
		}
	}
	
	public void after(JoinPoint point) {
		HandleDataSource.clear();
	}

	//这里可以捕获异常信息并保存
	public void afterThrowing(JoinPoint joinPoint, Throwable e){
		if (e != null) {
			System.out.println("[ =========== 捕获到异常信息开始 =========== ]");
			//发生异常的类
			String className = e.getClass().getName();
			System.out.println("发生异常的类: " + className);
			//发生异常的方法
			String methodName = joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()";
			System.out.println("发生异常的方法: " + methodName);
			//发生异常的详细信息
			String message = e.getMessage();
			System.out.println("发生异常信息: " + message);
			System.out.println("[ =========== 捕获到异常信息结束 =========== ]");
		}
	}
	
	public String getDataSourceName() {
		return dataSourceName;
	}

	public void setDataSourceName(String dataSourceName) {
		this.dataSourceName = dataSourceName;
	}
	
	/**
	 * 递归判断拦截方法的父类是否包含@DataSource注解
	 * @param clz
	 * @return
	 */
	public String hasDataSource(Class<?> clz){
		if (clz.getAnnotation(DataSource.class) != null) {
			return clz.getAnnotation(DataSource.class).value();
		}
		Class<?>[] classes = clz.getInterfaces();
		if (classes != null && classes.length > 0) {
			for (Class<?> clas : classes) {
				return hasDataSource(clas);
			}
		}
		return null;
	}

}
